import EventEmitter from './EventEmitter'
import { getItem, setItem, removeItem } from '@/utils/storage'

export default class NodeCode extends EventEmitter {
/**
 * 获取短信验证码
 * @param {String} queKey - 唯一标识, 如果存在, 在H5刷新或各端返回再进入时继续倒计时
 * @param {Number} seconds - 倒计时时长 默认60s
 * @return {Object}
 */
  constructor (queKey, seconds = 60) {
    super()
    this.queKey = queKey + '_$CountDownTimestamp'
    this.seconds = seconds
    this.keepRunning = !!queKey

    this.secNum = this.seconds
    this.timer = null
    this.canGetCode = true
  }

  // 订阅通知, 可以注册多个事件
  change (handler) {
    this.$on(this.queKey, handler)
    this.checkKeepRunning()
  }

  // 发布通知
  emit (data) {
    this.$emit(this.queKey, {
      msg: data,
      disabled: !this.canGetCode
    })
  }

  start () {
    // 防止快速点击获取验证码的按钮而导致内部产生多个定时器导致混乱
    if (this.timer) {
      clearInterval(this.timer)
      this.timer = null
    }

    this.canGetCode = false
    // 这里放这句，是为了一开始时就提示，否则要等setInterval的1秒后才会有提示
    this.emit(`${this.secNum}秒重新获取`)
    // 保存变量
    this.setTimeToStorage()
    this.timer = setInterval(() => {
      if (--this.secNum) {
        this.emit(`${this.secNum}秒重新获取`)
      } else {
        clearInterval(this.timer)
        this.timer = null
        this.secNum = this.seconds
        this.canGetCode = true
        this.emit('重新获取')
        // 清除本地保存的变量
        removeItem(this.queKey)
      }
    }, 1000)
  }

  // 重置，可以让用户再次获取验证码
  reset () {
    this.canGetCode = true
    clearInterval(this.timer)
    this.timer = null
    this.secNum = this.seconds
    this.emit('获取验证码')
  }

  // 销毁
  off () {
    this.canGetCode = true
    clearInterval(this.timer)
    this.timer = null
    this.secNum = this.seconds
    this.$off(this.queKey)
  }

  // 获取上一次退出页面(H5还包括刷新)时的时间戳，如果没有上次的保存，此值可能为空
  checkKeepRunning () {
    const lastTimestamp = Number(getItem(this.queKey))
    if (!lastTimestamp) return this.emit('获取验证码')
    // 当前秒的时间戳
    const nowTimestamp = Math.floor((+new Date()) / 1000)
    // 判断当前的时间戳，是否小于上一次的本该按设定结束，却提前结束的时间戳
    if (this.keepRunning && lastTimestamp && lastTimestamp > nowTimestamp) {
      // 剩余尚未执行完的倒计秒数
      this.secNum = lastTimestamp - nowTimestamp
      // 开始倒计时
      this.start()
    } else {
      // 清除本地保存的变量
      removeItem(this.queKey)
      // 如果不存在需要继续上一次的倒计时，执行正常的逻辑
      this.emit('获取验证码')
    }
  }

  // 保存时间戳，为了防止倒计时尚未结束，H5刷新或者各端的右上角返回上一页再进来
  setTimeToStorage () {
    if (!this.keepRunning) return
    // 记录当前的时间戳，为了下次进入页面，如果还在倒计时内的话，继续倒计时
    // 倒计时尚未结束，结果大于0；倒计时已经开始，就会小于初始值，如果等于初始值，说明没有开始倒计时，无需处理
    if (this.secNum > 0 && this.secNum <= this.seconds) {
      // 获取当前时间戳(+ new Date()为特殊写法)，除以1000变成秒，再去除小数部分
      const nowTimestamp = Math.floor((+new Date()) / 1000)
      // 将本该结束时候的时间戳保存起来 => 当前时间戳 + 剩余的秒数
      setItem(this.queKey, nowTimestamp + Number(this.secNum))
    }
  }
}
